/*
 *  mesh.h
 *  gmit
 *
 *  Description:
 *    This header constructs the components of mesh. It provides the underlying
 *    data structures.
 *    
 *
 *  Details:
 *    a. Methods start with "tie" is used to connect with external data.
 *    b. Methods start with "set" is used to solidify the external data.
 *    c. Some method started by "get" is not const, so the returned object can
 *       be modified. "getLocation" and "getUnitNorm" is const.
 *
 *  Created by DONG Li on 4/10/10.
 *  Copyright 2010 LASG/IAP. All rights reserved.
 *
 */

#ifndef MESH_H
#define MESH_H

#include <vector>

using namespace std;

// ************************************************************************ Grid

template <typename T>
class Grid
{
public:
    Grid() {}
    ~Grid() {}
    void setLocation(const vector<double>& x) { this->x = x; }
    const vector<double>& getLocation() const { return this->x; }
    bool isDuplicate(const Grid<T>& grid) const;
    void tieVariable(T* var) { this->var = var; }
    void setVariable(const T& var) { *(this->var) = var; }
    T& getVariable() const { return *(this->var); }
    
protected:
    vector<double> x;
    T* var; 
};

// ************************************************************************ Edge
class Edge
{
public:
    Edge() {}
    ~Edge() {}
    void addVertexGlobalId(int i);
    int getVertexGlobalId(int i) const { return this->vertexId[i]; }
    int getNumVertex() const { return this->vertexId.size(); }
    bool isDuplicate(const Edge& edge) const;
    void setUnitNorm(const vector<double>& norm) { this->unitNorm = norm; }
    const vector<double>& getUnitNorm() const;
    
protected:
    vector<int> vertexId;
    vector<double> unitNorm;
};

// ************************************************************************ Cell
class Cell
{
public:
    Cell() {}
    ~Cell() {}
    void addVertexGlobalId(int i) { this->vertexId.push_back(i); }
    int getVertexGlobalId(int i) const { return this->vertexId[i]; }
    int getNumVertex() const { return this->vertexId.size(); }
    void addEdgeGlobalId(int i) { this->edgeId.push_back(i); }
    int getEdgeGlobalId(int i) const { return this->edgeId[i]; }
    int getNumEdge() const { return this->edgeId.size(); }
protected:
    vector<int> vertexId;
    vector<int> edgeId;
};

// ********************************************************************* BndCell
class BndCell : public Cell
{
public:
    BndCell() {}
    ~BndCell() {}
    void setUnitNorm(const vector<double>& norm) { this->unitNorm = norm; }
    const vector<double>& getUnitNorm() const { return this->unitNorm; }
protected:
    vector<double> unitNorm;
};

// *****************************************************************************

#include "mesh.cpp"

// *****************************************************************************

class NoVar
{
};

#endif